package com.qingyun.shop.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.http.HttpStatus;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.qingyun.common.core.domain.entity.SysUser;
import com.qingyun.common.core.mybatisplus.core.ServicePlusImpl;
import com.qingyun.common.core.page.TableDataInfo;
import com.qingyun.common.exception.CustomException;
import com.qingyun.common.exception.ServiceException;
import com.qingyun.common.utils.DateUtils;
import com.qingyun.common.utils.PageUtils;
import com.qingyun.security.utils.SecurityUtils;
import com.qingyun.shop.domain.TiktokActivityToCoupon;
import com.qingyun.shop.domain.TiktokCoupon;
import com.qingyun.shop.domain.TiktokCouponDraw;
import com.qingyun.shop.domain.TiktokUserShop;
import com.qingyun.shop.domain.bo.coupon.TiktokCouponAddBo;
import com.qingyun.shop.domain.bo.coupon.TiktokCouponBo;
import com.qingyun.shop.domain.bo.coupon.TiktokCouponQueryBo;
import com.qingyun.shop.domain.vo.TiktokCouponListVo;
import com.qingyun.shop.domain.vo.TiktokCouponVo;
import com.qingyun.shop.domain.vo.TiktokUserCouponDrawList;
import com.qingyun.shop.mapper.*;
import com.qingyun.shop.service.ITiktokCouponDrawService;
import com.qingyun.shop.service.ITiktokCouponService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import ma.glasnost.orika.MapperFacade;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 优惠券Service业务层处理
 *
 * @author qingyun
 * @date 2021-09-04
 */
@Service
@AllArgsConstructor
@Slf4j
public class TiktokCouponServiceImpl extends ServicePlusImpl<TiktokCouponMapper, TiktokCoupon, TiktokCouponVo> implements ITiktokCouponService {

	private ITiktokCouponDrawService couponDrawService;

    private TiktokUserShopMapper userShopMapper;

    private MapperFacade mapperFacade;

    private TiktokActivityToCouponMapper activityToCouponMapper;

    private final TiktokCouponDrawMapper couponDrawMapper;

    private TiktokActivityMapper activityMapper;

    @Override
    public TiktokCouponVo queryById(Long id) {
        if (!SecurityUtils.isManager()) {
            if (count(Wrappers.lambdaQuery(TiktokCoupon.class)
                    .eq(TiktokCoupon::getShopId, SecurityUtils.getShop().getId())
                    .eq(TiktokCoupon::getId, id)) == 0) {
                throw new ServiceException("不能查询他人优惠卷信息");
            }
        }

        TiktokCouponVo vo = getVoById(id);

		List<String> actTitleByCoupId = activityToCouponMapper.getActTitleByCoupId(vo.getId());
		List<TiktokActivityToCoupon> activityToCoupon = activityToCouponMapper.selectList(Wrappers.query(new TiktokActivityToCoupon().setCouponId(vo.getId())));
        if (activityToCoupon != null) {
            vo.setIsRelevancy(Boolean.TRUE);
            vo.setActivityName(CollectionUtil.join(actTitleByCoupId,","));
        }

        return vo;
    }

    @Override
    public TableDataInfo<TiktokCouponListVo> queryPageList(TiktokCouponQueryBo bo) {
        if (!SecurityUtils.isManager()) {
            bo.setShopId(SecurityUtils.getShop().getId());
        }

        Page<TiktokCouponListVo> results = baseMapper.selectCouponList(PageUtils.buildPage(), bo);

        results.getRecords().forEach(c -> {
			List<String> actTitleByCoupId = activityToCouponMapper.getActTitleByCoupId(c.getId());
			if (CollectionUtil.isNotEmpty(actTitleByCoupId)) {
                c.setIsRelevancy(Boolean.TRUE);
                String title = CollectionUtil.join(actTitleByCoupId,",");
                c.setActivityName(title);
            } else {
                c.setIsRelevancy(Boolean.FALSE);
            }
            if (c.getTimeType() == 0 && c.getEndTime().after(new Date())) {
                c.setTimeRemaining("剩余" + DateUtils.getDatePoor(c.getEndTime(), new Date()));
            } else {
                c.setTimeRemaining("已过期");
            }
        });

        return PageUtils.buildDataInfo(results);
    }

    @Override
    public List<TiktokCouponVo> queryList(TiktokCouponQueryBo bo) {
        if (!SecurityUtils.isManager()) {
            bo.setShopId(SecurityUtils.getShop().getId());
        }
        return listVo(buildQueryWrapper(bo));
    }

    private LambdaQueryWrapper<TiktokCoupon> buildQueryWrapper(TiktokCouponQueryBo bo) {
        LambdaQueryWrapper<TiktokCoupon> lqw = Wrappers.lambdaQuery();
        lqw.eq(bo.getShopId() != null, TiktokCoupon::getShopId, bo.getShopId());
        lqw.like(StringUtils.isNotBlank(bo.getTitle()), TiktokCoupon::getTitle, bo.getTitle());
        lqw.ge(bo.getStartTime() != null, TiktokCoupon::getStartTime, bo.getStartTime());
        lqw.le(bo.getEndTime() != null, TiktokCoupon::getEndTime, bo.getEndTime());
        lqw.eq(bo.getType() != null, TiktokCoupon::getType, bo.getType());
        lqw.eq(bo.getStatus() != null, TiktokCoupon::getStatus, bo.getStatus());
		lqw.orderByDesc(TiktokCoupon::getId);
        return lqw;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean insertByBo(TiktokCouponAddBo bo) {
        TiktokCoupon add = BeanUtil.toBean(bo, TiktokCoupon.class);
        validEntityBeforeSave(add);
        SysUser user = SecurityUtils.getUser();
        if (!SecurityUtils.isManager()) {
            TiktokUserShop tiktokUserShop = userShopMapper.selectOne(Wrappers.lambdaQuery(TiktokUserShop.class)
                    .select(TiktokUserShop::getShopId).eq(TiktokUserShop::getUserId, user.getUserId()));
            Long shopId = tiktokUserShop.getShopId();
            add.setShopId(shopId);
        } else {
            if (ObjectUtil.isNull(add.getShopId())) {
                log.info("管理员添加优惠卷少商户参数");
                return false;
            }
        }
		if (add.getTimeType().equals(0)) {
			add.setStartTime(new Date());
			add.setEndTime(DateUtil.offsetDay(new Date(),add.getDays()));
		}
		if(add.getEndTime().before(new Date())){
			throw new CustomException("优惠卷过期时间不能在当前时间之前");
		}
        return save(add);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateByBo(TiktokCouponBo bo) {
        TiktokCoupon update = BeanUtil.toBean(bo, TiktokCoupon.class);
		if (update.getTimeType().equals(0)) {
			update.setStartTime(new Date());
			update.setEndTime(DateUtil.offsetDay(new Date(),update.getDays()));
		}
        validEntityBeforeSave(update);
        return updateById(update);
    }

    /**
     * 保存前的数据校验
     *
     * @param entity 实体类数据
     */
    private void validEntityBeforeSave(TiktokCoupon entity) {
        if (entity.getTimeType().equals(0)) {
            if (entity.getDays() < 0) {
                throw new ServiceException("优惠卷有效时间不能小于0", HttpStatus.HTTP_BAD_REQUEST);
            }
        } else {
            if (ObjectUtil.isNull(entity.getStartTime()) || ObjectUtil.isNull(entity.getEndTime())) {
                throw new ServiceException("开始时间和结束时间不能为空", HttpStatus.HTTP_BAD_REQUEST);
            }
            if (entity.getEndTime().before(entity.getStartTime())) {
                throw new ServiceException("结束日期不能在开始日期之前", HttpStatus.HTTP_BAD_REQUEST);
            }
            if (entity.getEndTime().before(new Date())) {
                throw new ServiceException("活动结束时间不能在当前时间之前");
            }
        }
        if (ObjectUtil.isNull(entity.getCollectionTimes())) {
            entity.setCollectionTimes(1);
        }
    }

	@Override
	public List<TiktokCouponDraw>  selectCouponDownList(Long activityId) {
		Long userId = SecurityUtils.getAppLoginUser().getSysUser().getUserId();
		List<TiktokCouponDraw> list = couponDrawService.list(Wrappers.lambdaQuery(TiktokCouponDraw.class).eq(TiktokCouponDraw::getActivityId, activityId).eq(TiktokCouponDraw::getUserId, userId));
		list.forEach((draw)->{
			TiktokCoupon coupon = this.getById(draw.getCouponId());
			draw.setCoupon(coupon);
		});
		return list;
	}

    @Override
    public TableDataInfo<TiktokUserCouponDrawList> selectCouponDownList(Long activityId, Integer status) {
        Long userId = SecurityUtils.getTikTokLoginUser().getTikTokUser().getId();

        Page<TiktokUserCouponDrawList> result = couponDrawMapper.selectTiktokUserCouponDrawList(PageUtils.buildPage(), userId, activityId, status);

        result.getRecords().forEach((draw)->{
            TiktokCoupon coupon = this.getById(draw.getCouponId());
            draw.setCoupon(coupon);
        });
		TableDataInfo<TiktokUserCouponDrawList> tiktokUserCouponDrawListTableDataInfo = PageUtils.buildDataInfo(result);
		return tiktokUserCouponDrawListTableDataInfo;
    }

    @Override

    public List<TiktokCouponVo> selectCouponVoByActivityId(Long ActivityId, Integer status) {
        List<TiktokCoupon> tiktokCoupons = baseMapper.selectCouponByActivityId(ActivityId, status);
        List<TiktokCouponVo> tiktokCouponVos = mapperFacade.mapAsList(tiktokCoupons, TiktokCouponVo.class);
        return tiktokCouponVos;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {

        if (isValid) {
            if (!SecurityUtils.isManager()) {
                Long id = SecurityUtils.getShop().getId();
                boolean b = list(lambdaQuery().select(TiktokCoupon::getShopId).in(TiktokCoupon::getId, ids)).stream().allMatch((coupon) -> {
                    return coupon.getShopId().equals(id);
                });
                if (!b) {
                    throw new ServiceException("非法删除");
                }
            }
			if (couponDrawService.count(Wrappers.lambdaQuery(TiktokCouponDraw.class).in(TiktokCouponDraw::getCouponId,ids))>0) {
				throw new ServiceException("优惠卷已经被用户领取无法删除");
			}
        }
        return removeByIds(ids);
    }

    /**
     * 修改优惠券状态
     *
     * @param id
     * @param status
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean modifiCouponStatus(Long id, Integer status) {
        TiktokCoupon coupon = baseMapper.selectById(id);
        if (coupon == null) {
            throw new ServiceException("优惠券不存在");
        }

        // 如果当前时间大于优惠券有效时期，则不让其修改
        if (coupon.getEndTime().before(new Date()) && status == 1) {
            throw new ServiceException("修改失败，当前优惠券已过期，请先去修改优惠券的有效时间再上架");
        }

        coupon.setStatus(status);

        return baseMapper.updateById(coupon) > 0;
    }

	@Override
	public Integer selectCouponCountByDate(Long shopId, Date date) {
		return baseMapper.selectCouponCountByDate(shopId,date);
	}

	@Override
	public Integer selectCheckCount(Long shopId) {
		return baseMapper.selectCheckCount(shopId);
	}

	@Override
	public Page<List<Map<String, Object>>> selectCheckDarwList(Long shopId) {

		return baseMapper.selectCheckDarwList(PageUtils.buildPage(),shopId);
	}

    /**
     * 今日核销
     *
     * @param id
     * @return
     */
    @Override
    public Integer selectCheckCountToDay(Long id) {
        return baseMapper.selectCheckCountToDay(id);
    }

    /**
     * 昨日核销
     *
     * @param id
     * @return
     */
    @Override
    public Integer selectCheckCountYesterday(Long id) {
        return baseMapper.selectCheckCountYesterday(id);
    }
}
